<template>
  <div class="render-target-prc">
    <!-- threejs官网的 ‘一些有用的链接’ -->
    <!-- 3D地球 -->
    <div class="canvas" ref="canvas"></div>
  </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-property-decorator';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const resource = import.meta.globEager('../../assets/*');
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
scene.add(camera);
{
  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(-1, 2, 4);
  scene.add(light);
}
{
  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(2, -5, -3);
  scene.add(light);
}
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
});
renderer.debug.checkShaderErrors = false;
renderer.setClearColor(new THREE.Color(), 0);
renderer.setPixelRatio(750 / window.innerWidth);

const fTexture = new THREE.TextureLoader().load(resource['../../assets/cloud.jpg'].default);
const VSHADER_SOURCE = `
    varying vec2 v_Uv;
    void main(){
      gl_Position = projectionMatrix * modelViewMatrix *vec4(position,1);
      v_Uv = uv;
    }
`;
const FSHADER_SOURCE = `
    uniform float time;
    uniform sampler2D fTexture;
    varying vec2 v_Uv;
    void main(){
      vec2 new_Uv  = fract(v_Uv + vec2(0,0.02) *time);
      gl_FragColor = texture2D(fTexture,new_Uv);
      float flag = gl_FragColor.x + gl_FragColor.y + gl_FragColor.z;
      flag /= 3.;
      flag = (flag-.7)*2.;
      gl_FragColor = vec4(1,1,1,flag);
    }
`;
const uniforms = {
  time: {
    value: 0.0,
  },
  fTexture: {
    value: fTexture,
  },
};
@Options({ components: {} })
export default class SpiralCircle extends Vue {
  public rect: DOMRect|null = null;

  public resizeRendererToDisplaySize(renderer: THREE.WebGLRenderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needSize = canvas.width !== width || canvas.height !== height;
    if (needSize) {
      renderer.setSize(width, height, false);
    }
    return needSize;
  }
  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    renderer.setSize(this.rect.width, this.rect.height, false);
    (this.$refs.canvas as HTMLDivElement).append(renderer.domElement);

    const group = new THREE.Group();

    // 创建一个基础球
    const geometry = new THREE.SphereGeometry(3);
    const loader = new THREE.TextureLoader();
    loader.load(resource['../../assets/earth.jpeg'].default, (texture) => {
      const material = new THREE.MeshLambertMaterial({
        map: texture,
      });
      const mesh = new THREE.Mesh(geometry, material);
      group.add(mesh);
    });

    // 创建外层大气球
    const cgeometry = new THREE.SphereGeometry(3.1);
    const cmaterial = new THREE.ShaderMaterial({
      uniforms,
      vertexShader: VSHADER_SOURCE,
      fragmentShader: FSHADER_SOURCE,
      transparent: true,
    });
    const cmesh = new THREE.Mesh(cgeometry, cmaterial);
    group.add(cmesh);
    scene.add(group);

    renderer.setAnimationLoop((time) => {
      cmaterial.uniforms.time.value += 0.1;
      group.rotation.y -= 0.005;
      renderer.render(scene, camera);
    });

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableZoom = false;
  }
}
</script>

<style lang="postcss" scoped>
  .render-target-prc{
    touch-action: none;
    position: absolute;
    left: 0;top: 0;
    width: 100%;height: 100%;
    background: #98bbd1;
    .canvas{
      position: absolute;
      left: 0;top: 0;
      width: 100%;height: 100%;
       :deep(canvas){
          width: 100%;height: 100%;
       }
    }
  }
</style>
